package com.party.web.web.controller.user;

import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.redis.StringJedis;
import com.party.common.utils.PasswordUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.log.BehaviorType;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.member.ThirdMember;
import com.party.core.model.resource.Resource;
import com.party.core.model.wechatPlatform.WechatOpenMember;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IThirdMemberService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.system.ISysRoleService;
import com.party.core.service.wechatPlatform.IWechatOpenMemberService;
import com.party.notify.notifyPush.servce.INotifySendService;
import com.party.web.biz.index.IndexBizService;
import com.party.web.biz.openPlatform.AuthorizationBizService;
import com.party.web.biz.system.menu.MenuBizService;
import com.party.web.biz.user.LoginBizService;
import com.party.web.utils.RealmUtils;
import com.party.web.web.annotation.UserOperate;
import com.party.web.web.dto.AjaxResult;
import com.party.web.web.dto.input.user.LoginInput;
import com.party.web.web.dto.input.user.ResetPwdInput;
import com.party.web.web.dto.output.index.IndexDictContentOutput;
import com.party.web.web.dto.output.index.IndexOutput;
import com.party.web.web.security.CurrentUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 登陆控制器
 * party
 * Created by wei.li
 * on 2016/8/26 0026.
 */

@Controller
@RequestMapping(value = "")
public class LoginController {

    protected static Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private IndexBizService indexBizService;

    @Autowired
    private INotifySendService notifySendService;

    @Autowired
    private IMemberGroupService memberGroupService;

    @Autowired
	StringJedis stringJedis;

    @Autowired
    private IWechatOpenMemberService wechatOpenMemberService;

    @Autowired
    private AuthorizationBizService authorizationBizService;

    @Autowired
    private IThirdMemberService thirdMemberService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private MenuBizService menuBizService;

    @Autowired
    private LoginBizService loginBizService;

    /**
     * 用户登陆
     * @param loginInput 登陆输入视图
     * @return 登陆返回结果
     */
    @UserOperate(moduleName = "用户", behaviorType = BehaviorType.LOGIN)
    @ResponseBody
    @RequestMapping(value = "/user/login/login", method = RequestMethod.POST)
    public AjaxResult login(@Validated LoginInput loginInput, BindingResult result){
        AjaxResult ajaxResult = new AjaxResult();
        //数据验证
        if (result.hasErrors()){
            List<ObjectError> allErros = result.getAllErrors();
            ajaxResult.setDescription(allErros.get(0).getDefaultMessage());
            return ajaxResult;
        }

        UsernamePasswordToken token
                = new UsernamePasswordToken(loginInput.getLoginName(), loginInput.getPassword());

        //获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();

        try {
            currentUser.login(token);
            logger.info("login{}", System.currentTimeMillis());
        } catch (UnknownAccountException ue) {
            logger.error("{}登陆账号不存在", loginInput.getLoginName());
            token.clear();
            currentUser.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
            ajaxResult.setDescription("账号不存在");
            return ajaxResult;
        }catch (IncorrectCredentialsException ie){
            logger.error("{}登陆密码错误", loginInput.getLoginName());
            token.clear();
            currentUser.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
            ajaxResult.setDescription("密码错误");
            return ajaxResult;
        }
        //获取菜单放到缓存
        CurrentUser newCurrentUser = RealmUtils.getNewCurrentUser();
        String memberId = newCurrentUser.getId();
        redisTemplate.delete("myWebMenuTree_" + memberId);

        return loginBizService.getForwardUrl(token, currentUser, newCurrentUser);
    }

    /**
     * 校验账号是否授权
     * @return
     */
    @RequestMapping("/user/login/checkIsConfig")
    @ResponseBody
    public AjaxResult checkIsConfig(String loginName) {
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.setSuccess(true);
        MemberGroup member = memberGroupService.findByLoginName(loginName, Constant.MEMBER_ORGANIZATION);
        if (null == member || null == member.getId()) {
//            ajaxResult.setDescription("该账号不存在");
            return ajaxResult;
        }
        Integer openStatus = member.getOpenStatus();
        if (openStatus == null || openStatus == 0) {
            ajaxResult.setDescription("该账号还未授权, 请先授权后登录");
            ajaxResult.setSuccess(false);
            return ajaxResult;
        }
        return ajaxResult;
    }


    /**
     * 退出登陆
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/user/login/logout")
    public AjaxResult logout(){
        redisTemplate.delete("myWebMenuTree_"+ RealmUtils.getCurrentUser().getId());
        SecurityUtils.getSubject().logout();
        return AjaxResult.success();
    }


    /**
     * 登陆页面
     * @return
     */
    @RequestMapping(value = "/user/login/home")
    public ModelAndView home(){
//        ModelAndView modelAndView = new ModelAndView("index");
//        IndexOutput  indexOutput = indexBizService.getIndex();
//        modelAndView.addObject("index", indexOutput);
        MemberGroup currentUser = RealmUtils.getCurrentUser();
        if (currentUser != null && currentUser.getUsername().equals("thirdMemberManage")) {
            RealmUtils.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
            RealmUtils.getSession().removeAttribute(Constant.THIRD_USER_KEY);
        }
//        return modelAndView;
        ModelAndView modelAndView = new ModelAndView("index");
        List<IndexDictContentOutput> articleList = indexBizService.typeWithArticleList(new Page(1, 4));
        modelAndView.addObject("articleList", articleList);
        return modelAndView;
    }

    /**
     * 新的主页
     *
     * @return
     */
    @RequestMapping(value = "/user/login/newHome")
    public ModelAndView newHome() {
        ModelAndView modelAndView = new ModelAndView("index");
        List<IndexDictContentOutput> articleList = indexBizService.typeWithArticleList(new Page(1, 4));
        modelAndView.addObject("articleList", articleList);
        return modelAndView;
    }



    /**
     * 初始化页面
     * @return 初始化页面
     */
    @RequestMapping(value = "/user/login/defalt")
    public String defalt(){
        return "defalt";
    }

    /**
     * 没有授权
     * @return
     */
    @RequestMapping(value = "/user/login/noAuthorization")
    public String noAuthorization(){
        return "401";
    }


    /**
     * 登陆页面
     * @return
     */
    @RequestMapping(value = "/user/login/loginView")
    public String loginView(){
        return "login";
    }

    /**
     * 发送手机验证码
     * @return 交互数据
     */
    @ResponseBody
    @RequestMapping(value = "/user/login/getCode")
    public AjaxResult getCode(String mobile){

        if (StringUtils.isEmpty(mobile)) {
			return new AjaxResult(false);
		}

        notifySendService.sendVerifyCode(mobile);
        return AjaxResult.success();
    }

	/**
	 * 找回密码
	 *
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/user/login/resetPassword")
	public AjaxResult resetPassword(@Validated ResetPwdInput resetPwdInput, BindingResult result) {
		// 数据验证
		if (result.hasErrors()) {
			List<ObjectError> allErros = result.getAllErrors();
			return AjaxResult.error(allErros.get(0).getDefaultMessage());
		}

        //加短信开关
        boolean isVerify = sysConfigService.isVerifySms();
        if (isVerify){
            // 验证验证码
            String verifyCode = stringJedis.getValue(resetPwdInput.getMobile());
            if (null == verifyCode || !verifyCode.equals(resetPwdInput.getVerifyCode())) {
                return AjaxResult.error("手机验证码不一致");
            }
        }

		MemberGroup member = memberGroupService.findByPhone(resetPwdInput.getMobile(), Constant.MEMBER_ORGANIZATION);
		if (member == null) {
			return AjaxResult.error("用户不存在");
		}

		String encryptPassword = PasswordUtils.encryptPassword(resetPwdInput.getPassword());
		member.setPassword(encryptPassword);
		memberGroupService.update(member);
		return AjaxResult.success();
	}

    /**
     * 重置退款密码
     * @return
     */
	@ResponseBody
    @RequestMapping("/user/resetRefundPassword")
	public AjaxResult resetRefundPassword(@Validated ResetPwdInput resetPwdInput, BindingResult result) {
        // 数据验证
        if (result.hasErrors()) {
            List<ObjectError> allErros = result.getAllErrors();
            return AjaxResult.error(allErros.get(0).getDefaultMessage());
        }

        // 加短信开关
        boolean isVerify = sysConfigService.isVerifySms();
        if (isVerify){
            // 验证验证码
            String verifyCode = stringJedis.getValue(resetPwdInput.getMobile());
            if (null == verifyCode || !verifyCode.equals(resetPwdInput.getVerifyCode())) {
                return AjaxResult.error("手机验证码不一致");
            }
        }

        MemberGroup member = memberGroupService.findByPhone(resetPwdInput.getMobile(), Constant.MEMBER_ORGANIZATION);
        if (member == null) {
            return AjaxResult.error("用户不存在");
        }
        String encryptPassword = PasswordUtils.encryptPassword(resetPwdInput.getPassword());
        member.setRefundPassword(encryptPassword);
        memberGroupService.update(member);
        return AjaxResult.success();
    }

	/**
     * 合作商登录
     * @return 合作商登录
     */
    @RequestMapping(value = "/pLogin")
    public ModelAndView partnerLogin(){
    	ModelAndView mv = new ModelAndView("partner_login");
    	List<Resource> partners = indexBizService.getPartner();
    	IndexOutput indexOutput = new IndexOutput();
    	indexOutput.setResources(partners);
    	mv.addObject("index", indexOutput);
        return mv;
    }

    @ResponseBody
    @RequestMapping(value = "test")
    public AjaxResult test(){
        WechatOpenMember wechatOpenMember = wechatOpenMemberService.list(new WechatOpenMember()).get(0);
        authorizationBizService.synchronousMenu(wechatOpenMember.getAuthorizerAccessToken(), wechatOpenMember.getMemberId());
        return AjaxResult.success();
    }

    /**
     * 第三方用户登录
     * @return
     */
    @RequestMapping(value = "/thirdLogin")
    public ModelAndView thirdLogin(){
        ModelAndView mv = new ModelAndView("third_login");
        List<Resource> partners = indexBizService.getPartner();
        IndexOutput indexOutput = new IndexOutput();
        indexOutput.setResources(partners);
        mv.addObject("index", indexOutput);
        return mv;
    }

    /**
     * 第三方用户登录
     * @param loginInput
     * @param result
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/user/login/doThirdLogin")
    public AjaxResult doThirdLogin(@Validated LoginInput loginInput, BindingResult result, HttpServletRequest request){
        AjaxResult ajaxResult = new AjaxResult();
        //数据验证
        if (result.hasErrors()){
            List<ObjectError> allErros = result.getAllErrors();
            ajaxResult.setDescription(allErros.get(0).getDefaultMessage());
            return ajaxResult;
        }

        ThirdMember thirdMember = new ThirdMember();
        thirdMember.setAccount(loginInput.getLoginName());
        thirdMember.setPassword(loginInput.getPassword());

        ThirdMember unique = thirdMemberService.getUnique(thirdMember);
        if (unique == null) {
            return AjaxResult.error("账号或密码错误");
        } else {
            MemberGroup thirdMemberManage = memberGroupService.getThirdMemberManage();
            loginInput.setLoginName(thirdMemberManage.getUsername());
            loginInput.setPassword(thirdMemberManage.getPassword());

            UsernamePasswordToken token
                    = new UsernamePasswordToken(loginInput.getLoginName(), Constant.DEFALT_PASSWORD);
            logger.error("new token {}", System.currentTimeMillis());

            //获取当前的Subject
            Subject currentUser = SecurityUtils.getSubject();
            logger.error("getSubject {}", System.currentTimeMillis());
            try {
                currentUser.getSession().setAttribute(Constant.THIRD_USER_KEY, unique);
                if (StringUtils.isNotEmpty(unique.getPublisher())) {
                    MemberGroup publisher = memberGroupService.get(unique.getPublisher());
                    currentUser.getSession().setAttribute("businessPublisher", publisher);
                }

                currentUser.login(token);
                logger.info("login{}", System.currentTimeMillis());
            } catch (UnknownAccountException ue) {
                logger.error("{}登陆账号不存在", loginInput.getLoginName());
                token.clear();
                currentUser.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
                ajaxResult.setDescription("账号不存在");
                return ajaxResult;
            }catch (IncorrectCredentialsException ie){
                logger.error("{}登陆密码错误", loginInput.getLoginName());
                token.clear();
                currentUser.getSession().removeAttribute(Constant.CURRENT_USER_KEY);
                ajaxResult.setDescription("密码错误");
                return ajaxResult;
            }

            ajaxResult.setDescription(unique.getUri());
            ajaxResult.setSuccess(true);
            return ajaxResult;
        }
    }
}
